package com.xuecheng.learning.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.base.model.PageResult;
import com.xuecheng.content.model.po.CoursePublish;
import com.xuecheng.learning.feignclient.ContentServiceClient;
import com.xuecheng.learning.mapper.XcChooseCourseMapper;
import com.xuecheng.learning.mapper.XcCourseTablesMapper;
import com.xuecheng.learning.model.dto.MyCourseTableParams;
import com.xuecheng.learning.model.dto.XcChooseCourseDto;
import com.xuecheng.learning.model.dto.XcCourseTablesDto;
import com.xuecheng.learning.model.po.XcChooseCourse;
import com.xuecheng.learning.model.po.XcCourseTables;
import com.xuecheng.learning.service.MyCourseTablesService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.sql.Wrapper;
import java.time.LocalDateTime;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ws
 * Date: 2024-07-23
 * Time: 17:51
 */
@Slf4j
@Service
public class MyCourseTablesServiceImpl implements MyCourseTablesService {

    @Autowired
    XcChooseCourseMapper xcChooseCourseMapper;

    @Autowired
    XcCourseTablesMapper xcCourseTablesMapper;

    @Autowired
    ContentServiceClient contentServiceClient;

    @Autowired
    MyCourseTablesService myCourseTablesService;

    @Autowired
    MyCourseTablesServiceImpl currentProxy;

    @Resource
    XcChooseCourseMapper chooseCourseMapper;

    @Resource
    XcCourseTablesMapper courseTablesMapper;

    @Transactional
    @Override
    public XcChooseCourseDto addChooseCourse(String userId, Long courseId) {
        //查询课程信息
        CoursePublish coursepublish = contentServiceClient.getCoursepublish(courseId);
        //课程收费标准
        String charge = coursepublish.getCharge();
        //选课记录
        XcChooseCourse chooseCourse = null;
        if ("201000".equals(charge)) {//课程免费
            // 添加免费课程
            chooseCourse = addFreeCourse(userId, coursepublish);
            // 添加到我的课程表
            XcCourseTables xcCourseTables = addCourseTables(chooseCourse);
        } else {
            //添加收费课程
            chooseCourse = addChargeCourse(userId, coursepublish);
        }
        // 获取学习资格
        XcCourseTablesDto courseTablesDto = getLearningStatus(userId, courseId);
        // 设置返回值
        XcChooseCourseDto xcChooseCourseDto = new XcChooseCourseDto();
        BeanUtils.copyProperties(chooseCourse, xcChooseCourseDto);
        xcChooseCourseDto.setLearnStatus(courseTablesDto.getLearnStatus());

        return xcChooseCourseDto;
    }

    // 学习资格，
    // [{"code":"702001","desc":"正常学习"},
    // {"code":"702002","desc":"没有选课或选课后没有支付"},
    // {"code":"702003","desc":"已过期需要申请续期或重新支付"}]
    @Override
    public XcCourseTablesDto getLearningStatus(String userId, Long courseId) {
        // 获取我的课程表，如果没有对应的记录，直接结束
        XcCourseTables xcCourseTables = getXcCourseTables(userId, courseId);
        XcCourseTablesDto xcCourseTablesDto = new XcCourseTablesDto();
        if (xcCourseTables == null) {
            xcCourseTablesDto.setLearnStatus("702002");
            return xcCourseTablesDto;
        }
        // 如果查到了，判断是否过期
        if (xcCourseTables.getValidtimeEnd().isBefore(LocalDateTime.now())) {
            // 过期了
            xcCourseTablesDto.setLearnStatus("702003");
            return xcCourseTablesDto;
        }
        // 正常学习
        BeanUtils.copyProperties(xcCourseTables, xcCourseTablesDto);
        xcCourseTablesDto.setLearnStatus("702001");

        return xcCourseTablesDto;
    }

    //添加免费课程,免费课程加入选课记录表、我的课程表
    public XcChooseCourse addFreeCourse(String userId, CoursePublish coursepublish) {
        // 免费课程，只要有记录就行，无所谓属于哪个 userId
        // 如果存在课程记录，直接返回
        List<XcChooseCourse> xcChooseCourses = xcChooseCourseMapper.selectList(Wrappers.<XcChooseCourse>lambdaQuery().
                eq(XcChooseCourse::getCourseId, coursepublish.getId()).
                eq(XcChooseCourse::getOrderType, "700001"). // 免费课程
                        eq(XcChooseCourse::getStatus, "701001") // 选课成功
        );
        // 说明之前有记录，就返回这条记录就行
        if (!CollectionUtils.isEmpty(xcChooseCourses)) {
            // 因为没有主键约束，可能有多条记录，取第一条即可
            return xcChooseCourses.get(0);
        }
        // 向选课记录表添加记录
        XcChooseCourse xcChooseCourse = new XcChooseCourse();
        xcChooseCourse.setCourseId(coursepublish.getId());
        xcChooseCourse.setCourseName(coursepublish.getName());
        xcChooseCourse.setUserId(userId); // 免费课程其实无所谓 userId
        xcChooseCourse.setCompanyId(coursepublish.getCompanyId());
        xcChooseCourse.setOrderType("700001");
        xcChooseCourse.setStatus("700001");
        xcChooseCourse.setCreateDate(LocalDateTime.now());
        xcChooseCourse.setCoursePrice(coursepublish.getPrice());
        xcChooseCourse.setValidDays(coursepublish.getValidDays()); // 有效天数
        xcChooseCourse.setValidtimeStart(LocalDateTime.now()); // 有效期开始时间
        xcChooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(coursepublish.getValidDays())); // 有效期结束时间
        int insert = xcChooseCourseMapper.insert(xcChooseCourse);
        if (insert <= 0) {
            XueChengPlusException.cast("添加选课记录失败");
        }
        return xcChooseCourse;
    }

    // 添加收费课程，要和订单支付模块有关，没有完成支付前，不能向我的课程表添加记录
    public XcChooseCourse addChargeCourse(String userId, CoursePublish coursepublish) {
        // 如果存在课程记录，且状态为待支付，直接返回
        List<XcChooseCourse> xcChooseCourses = xcChooseCourseMapper.selectList(Wrappers.<XcChooseCourse>lambdaQuery().
                eq(XcChooseCourse::getCourseId, coursepublish.getId()).
                eq(XcChooseCourse::getOrderType, "700002"). // 收费课程
                        eq(XcChooseCourse::getStatus, "701002") // 待支付
        );
        // 说明之前有记录，就返回这条记录就行
        if (!CollectionUtils.isEmpty(xcChooseCourses)) {
            // 因为没有主键约束，可能有多条记录，取第一条即可
            return xcChooseCourses.get(0);
        }
        // 向选课记录表添加记录
        XcChooseCourse xcChooseCourse = new XcChooseCourse();
        xcChooseCourse.setCourseId(coursepublish.getId());
        xcChooseCourse.setCourseName(coursepublish.getName());
        xcChooseCourse.setUserId(userId); // 免费课程其实无所谓 userId
        xcChooseCourse.setCompanyId(coursepublish.getCompanyId());
        xcChooseCourse.setOrderType("700002");
        xcChooseCourse.setStatus("701002");
        xcChooseCourse.setCreateDate(LocalDateTime.now());
        xcChooseCourse.setCoursePrice(coursepublish.getPrice());
        xcChooseCourse.setValidDays(coursepublish.getValidDays()); // 有效天数
        xcChooseCourse.setValidtimeStart(LocalDateTime.now()); // 有效期开始时间
        xcChooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(coursepublish.getValidDays())); // 有效期结束时间
        int insert = xcChooseCourseMapper.insert(xcChooseCourse);
        if (insert <= 0) {
            XueChengPlusException.cast("添加选课记录失败");
        }
        return xcChooseCourse;
    }

    // 添加到我的课程表
    public XcCourseTables addCourseTables(XcChooseCourse xcChooseCourse) {
        String status = xcChooseCourse.getStatus();
        if (!"701001".equals(status)) {
            XueChengPlusException.cast("选课没有成功，无法添加到课程表");
        }
        XcCourseTables xcCourseTables = getXcCourseTables(xcChooseCourse.getUserId(), xcChooseCourse.getCourseId());
        if (xcCourseTables != null) {
            return xcCourseTables;
        }
        xcCourseTables = new XcCourseTables();
        BeanUtils.copyProperties(xcChooseCourse, xcCourseTables);
        xcCourseTables.setChooseCourseId(xcChooseCourse.getId());
        xcCourseTables.setCourseType(xcChooseCourse.getOrderType());
        xcCourseTables.setUpdateDate(LocalDateTime.now());
        int insert = xcCourseTablesMapper.insert(xcCourseTables);
        if (insert <= 0) {
            XueChengPlusException.cast("添加到我的课程表失败");
        }

        return xcCourseTables;
    }


    /**
     * @param userId
     * @param courseId
     * @return com.xuecheng.learning.model.po.XcCourseTables
     * @description 根据课程和用户查询我的课程表中某一门课程
     */
    public XcCourseTables getXcCourseTables(String userId, Long courseId) {
        XcCourseTables xcCourseTables = xcCourseTablesMapper.selectOne(new LambdaQueryWrapper<XcCourseTables>().
                eq(XcCourseTables::getUserId, userId).
                eq(XcCourseTables::getCourseId, courseId)
        );
        return xcCourseTables;

    }


    @Transactional
    @Override
    public boolean saveChooseCourseSuccess(String chooseCourseId) {

        //根据choosecourseId查询选课记录
        XcChooseCourse xcChooseCourse = chooseCourseMapper.selectById(chooseCourseId);
        if (xcChooseCourse == null) {
            log.debug("收到支付结果通知没有查询到关联的选课记录,choosecourseId:{}", chooseCourseId);
            return false;
        }
        String status = xcChooseCourse.getStatus();
        if ("701001".equals(status)) {
            //添加到课程表
            addCourseTables(xcChooseCourse);
            return true;
        }
        //待支付状态才处理
        if ("701002".equals(status)) {
            //更新为选课成功
            xcChooseCourse.setStatus("701001");
            int update = chooseCourseMapper.updateById(xcChooseCourse);
            if (update > 0) {
                log.debug("收到支付结果通知处理成功,选课记录:{}", xcChooseCourse);
                //添加到课程表
                addCourseTables(xcChooseCourse);
                return true;
            } else {
                log.debug("收到支付结果通知处理失败,选课记录:{}", xcChooseCourse);
                return false;
            }
        }

        return false;
    }


    @Override
    public PageResult<XcCourseTables> mycoursetables(MyCourseTableParams params) {
        //页码
        long pageNo = params.getPage();
        //每页记录数
        long pageSize = params.getSize();
        //分页条件
        Page<XcCourseTables> page = new Page<>(pageNo, pageSize);
        //根据用户id查询
        String userId = params.getUserId();
        LambdaQueryWrapper<XcCourseTables> lambdaQueryWrapper = new LambdaQueryWrapper<XcCourseTables>().eq(XcCourseTables::getUserId, userId);

        //分页查询
        Page<XcCourseTables> pageResult = courseTablesMapper.selectPage(page, lambdaQueryWrapper);
        List<XcCourseTables> records = pageResult.getRecords();
        //记录总数
        long total = pageResult.getTotal();
        PageResult<XcCourseTables> courseTablesResult = new PageResult<>(records, total, pageNo, pageSize);
        return courseTablesResult;

    }

}